#include <iostream>
#include "library1.h"
#include "hrsystem.h"

using std::bad_alloc;

#define TO_HRSYSTEM(_HR_SYSTEM_) (*(HRSystem*)(_HR_SYSTEM_))
#define TRY_CATCH_EXCEPTIONS(_TRY_CODE_)  \
	try{ \
		_TRY_CODE_ ; \
	}\
	catch (const bad_alloc&) { \
		return ALLOCATION_ERROR; \
	} \
	catch (const InvalidInputExcpetion&) { \
		return INVALID_INPUT; \
	} \
	catch (const FailureException& e3) { \
		return FAILURE; \
	}


bool isNull(void* ptr) {
	return (ptr == NULL);
}



void*       Init(int K) {
	try {
		return new HRSystem(K);
	}
	catch(...) {
		return NULL;
	}
}

StatusType  Hire(void* DS, int id, int company, Rational salary) {
	if (isNull(DS)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( TO_HRSYSTEM(DS).HireEmployee(id,salary,company))
	return SUCCESS;
}

StatusType  Fire(void* DS, int id, int company) {
	if (isNull(DS)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( TO_HRSYSTEM(DS).FireEmployee (id,company))
	return SUCCESS;
}

StatusType  GetEmployer(void* DS, int id, int* company) {
	if (isNull(DS) || isNull(company)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( *company = TO_HRSYSTEM(DS).GetEmployer(id))
	return SUCCESS;
}

StatusType  GetSalary(void* DS, int id, Rational* salary) {
	if (isNull(DS) || isNull(salary)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS ( *salary = TO_HRSYSTEM(DS).GetSalary(id))
	return SUCCESS;
}

StatusType  MedianSalary(void* DS, int company, Rational* salary) {
	if (isNull(DS) || isNull(salary)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( *salary = TO_HRSYSTEM(DS).GetMedianSalary(company));
	return SUCCESS;
}

StatusType  HighestSalary(void* DS, int company, Rational* salary) {
	if (isNull(DS) || isNull(salary)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( *salary = TO_HRSYSTEM(DS).GetHeighestSalary(company));
	return SUCCESS;
}

StatusType  UpdateSalaries(void* DS, int company, Rational update) {
	if (isNull(DS)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( TO_HRSYSTEM(DS).UpdateSalaries (company,update))
	return SUCCESS;
}

StatusType  Merger(void* DS, int buyingCompany, int sellingCompany) {
	if (isNull(DS)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( TO_HRSYSTEM(DS).Merger (buyingCompany,sellingCompany))
	return SUCCESS;
}

void Quit(void** DS)
{
	if (DS==NULL)
	{
		return;
	}
	delete *((HRSystem**)DS);
	*DS = NULL;
}

